// ts中枚举又是类型又是值

// ------------------- 1. 应用 -------------------
// 创建好后，默认就有映射
// 字符串->数字  字符串->字符串
enum Color {
  Red,
  Green = 200,
  Blue,
}
// 枚举是双向映射的，可以通过枚举值找到枚举名，也可以通过枚举名找到枚举值
Color.Red; // 0
Color[201]; // Blue
// ------------------- 2. attention -------------------
/**
 * 如果是普通业务，没有什么问题
 * 但是如果是一个ts写的库，需要提供给别人使用，那么就需要注意，枚举类型变成了立即执行函数「IIFE」
 * 无法被 tree shaking 优化掉，因为这个IIFE有副作用
 */

enum AttackType {
  None = 0, // 0000
  Melee = 1, // 0001
  Fire = 2, // 0010
  Ice = 4, // 0100
  Poison = 8, // 1000
}
// 或运算
const attack = AttackType.Melee | AttackType.Fire | AttackType.Poison; // 1011

const attackMethod = (attack: AttackType) => console.log(attack);

attackMethod(attack); // 11

// 枚举的tsconfig.json配置
/**
 * 如果在工程中使用枚举类型，务必要设置tsconfig的属性isolatedModules为true,因为有些打包工具并没有依赖
 * Typescript的tsc进行类型检查和类型转移，像esbuild、babel这样的工具会单独编译每个文件，因此它们无法判断
 * 导入的名称是类型还是值。所以有一些Typescript的特性是容易产生错误的，比如 const enum。这个内容在
 * vite和esbuild中都有相关的说明。
 */

// ------------------- 3. 常量枚举 -------------------
/**
 * 常量枚举是一种特殊的枚举，它会在编译阶段被删除，并且不能包含计算成员
 * 不会产生javascript对象、IIFE代码，而是在用到的地方直接替换成对应的值
 * 常量枚举不允许反向查找
 */
const enum Direction2 {
  Up,
  Down,
  Left,
  Right,
}
console.log(Direction2.Up);

export {};
